/******************************************************************************
Javascript module for very simple english query parsing
Some source obtained from: http://jqueryui.com/demos/autocomplete/
******************************************************************************/
// show teams founded before 1950
NLP = function() {
	var autoidx;			/** autoindex element */
	var autoidx_error;		/** autoindex error div */
	
	var state_lists = [];
	var current_states = {};
	
	var init_state_list = function() {
		var attrs = [];
		var operations = [];
		
		$.each(METADATA, function(index, value) {
			attrs.push(value.key);
		});
		
		operations = [];
		$.each(SimpleOperations, function(index, value) {
			operations.push(value.value);
		});
		
		state_lists = [
			['show'],
			attrs,
			['of'],
			['teams', 'players'],
			['with'],
			attrs,
			operations
		];
	};
	
	var parse_and_suggest = function(query) {
		UI.log('parse_and_suggest');
		var terms = query.split(" ");
		var current = terms.pop();

		validate_terms(terms);
		UI.log('terms validated');
		
		var idx = terms.length;
		UI.log('cur idx:' + idx);
		UI.log('current: [' + current + ']');

		var chk_idx = (idx < state_lists.length) ? idx : state_lists.length -1;
		return $.ui.autocomplete.filter(
		 	state_lists[chk_idx], current);
	};
	
	var parse_and_create_query_params = function(query) {
		UI.log('parse_and_create_query_params');
        var sentence = $.trim(query);
		var terms = sentence.split(" ");
		validate_terms(terms);
		
		/** simple operations  only! */
		var display_attr = terms[1];
		var subject = terms[3];
		var attr = terms[5];
		var operation = terms[6];
		var value = terms.splice(7,terms.length).join(' ');
		
		return {
			'display_attr':display_attr,
			'subject':subject,
			'attr':attr,
			'value':value,
			'operation':operation
		};
	};
	
	/** simple validation, throw exception*/
	var validate_terms = function(terms) {
		reset_errors();
		var errors = [];
		$.each(terms, function(idx, value) {
			var valid_list = state_lists[idx];
			if (valid_list === undefined) {
				return;
			}
			UI.log('Validate [' + value + '] in ' + valid_list.join(','));
			UI.log('Index: ' + idx +' : MaxIdx: ' + terms.length);
			/** perform exact matching previous indices */
			if (idx < terms.length) {
				UI.log("...doing exact match validation");		
				if ($.inArray(value, valid_list) < 0) {
					errors.push(value)
				}
			} else {
				UI.log("...doing substring validation");
				/** perform substring validation of current index */
				var found = false;
				var local_errs = [];		
				$.each(valid_list, function(item_idx, item) {
					if (item.toLowerCase().indexOf(value.toLowerCase()) < 0)
						local_errs.push(value);
					else {
						found = true;
						return false;
					}
				});
				/** add any loop errors to main list */
				if (!found) {
					errors.extend(local_errs);
				}
			}
		});
		UI.log('errors: ' + errors.join(','))
		if (errors.length > 0) {
			UI.log('found error');
			throw {
				'error_type':'Invalid Syntax', 
				'errors':errors
			};
		}
	}
	
	/** expect Error map **/
	var show_errors = function(error) {
		var errs = error.errors || [];
		autoidx_error.append(
			"Sorry, I don't understand the words: " +
			errs.join(', ') + ".");
	}
	
	var reset_errors = function() {
		autoidx_error.empty();
	}
	
	/** Public **/
	return {
		init : function(configuration) {
			var conf = configuration || {};
			autoidx = $(conf.autoidx);
			autoidx_error = $(conf.autoidx_error);
			autoidx
				.bind("keydown", function(event) {
					if (event.keyCode === $.ui.keyCode.TAB &&
						$(this).data("autocomplete").menu.active) {
							event.preventDefault();
							this.value = this.value + ' ';
						}
				})
				.bind("focus", function(event) {
					UI.log("got focus event");
					autoidx.autocomplete("search", autoidx.val());
				})
				.autocomplete({
					source: NLP.generate_suggestions,
					focus: function(event, ui) {
						UI.log('focus fired');
						event.preventDefault();
						return false;
					},
					select: function(event,ui) {
						/** replace last element with selection **/
						UI.log('select fired');
                        var sentence = $.trim(autoidx.val());
						var terms = sentence.split(" ");
						terms.pop();
						terms.push(ui.item.value);
						autoidx.val(terms.join(' ') + ' ');
						event.preventDefault();
					}
				});	
			init_state_list();		
		},
		
		/** 
			jquery-ui autocomplete callback function 
			@param request - contains 'term' property with current value
			@param response - callback expects string-array or object-array
		*/
		generate_suggestions : function(request, response) {
			// request.term : contains value currently in input
			var avail = [];
			try {
				avail = parse_and_suggest(request.term);
			} catch (err) {
				UI.log('*** error during parse/suggest: ' + err);
				show_errors(err);
			}
			response(avail);
		},
		
		reset : function() {
			reset_errors();
		},
		
		/** Construct the query information needed */
		construct_query : function() { 
			try {
				return parse_and_create_query_params(autoidx.val());
			} catch (err) {
				UI.log('*** error during construct_query: ' + err);
				show_errors(err);
				return null;
			}
		}
	}
}();

